﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FileHelpers;
using MoneyWentWhere.Utils;

namespace MoneyWentWhere.SimpleTextFile
{
    [DelimitedRecord(",")]
    [IgnoreEmptyLines]
    public class Account
    {
        public const String TypeId = "A";
        private String _typeId = TypeId;

        // Type: A
        [FieldConverter(typeof(StringConverter))]
        public String Currency;

        [FieldQuoted(QuoteMode.OptionalForBoth)]
        [FieldConverter(typeof(StringConverter))]
        public String Name;

        [FieldQuoted(QuoteMode.OptionalForBoth, MultilineMode.AllowForBoth)]
        [FieldConverter(typeof(StringConverter))]
        public String Comment;

        [FieldQuoted(QuoteMode.OptionalForBoth)]
        [FieldConverter(typeof(StringConverter))]
        public String Group;

        [FieldQuoted(QuoteMode.OptionalForBoth)]
        [FieldConverter(typeof(StringConverter))]
        public String Url;
        
        // Filled on 2nd pass
        [FieldIgnored]
        private List<Transaction> _transactions = new List<Transaction>();

        public List<Transaction> Transactions { get { return _transactions; } }

        #region Stats

        public decimal BalanceAt(DateTime date)
        {
            // LINQ is more complex here and performs worse
            // Iterate backwards
            decimal sum = 0;
            for (int i=Transactions.Count-1; i>=0; i--)
            {
                Transaction tx = Transactions[i]; 
                if (tx.Date > date) { continue; }
                
                Reconcile recoTx = tx as Reconcile;
                if (recoTx != null) { return sum + recoTx.Balance; }

                sum += tx.Amount;
            }
            return sum;
        }

        public decimal Balance { get { return BalanceAt(DateTime.MaxValue); } }

        #endregion

        #region File processing
        // Called after data and transactions have been adde
        // Check field integrity etc.
        public void OnAfterRead()
        {
            Currency = Currency.RemoveDelims();
            Name = Name.RemoveDelims();
            Group = Group.RemoveDelims();
            
            InitializeTransactions();
        }

        void InitializeTransactions()
        {
            Transaction prevTx = null;
            foreach (Transaction tx in Transactions)
            {
                tx.Account = this;

                // Adjust the date
                if (prevTx != null)
                {
                    if (prevTx.Date > tx.Date)
                    {
                        tx.Date = prevTx.Date;
                    }
                }

                prevTx = tx;
            }
        }
        #endregion


    }
}
